<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2018/6/5
 * Time: 16:44
 */

namespace app\api\controller;

use app\common\cachemodel\AppUserForbidDeviceRecord;
use app\common\lib\Util;
use think\Controller;
use app\common\lib\exception\ApiException;
use app\common\lib\IAuth;
use think\Log;

/**
 * API模块 公共的控制器
 * Class Common
 * @package app\api\controller
 */
class Common extends Controller
{
    /**
     * headers信息
     * @var array
     */
    public $headers = [];
    public $CT = 1; // 客户端类型 1=>APP 2=>小程序｜H5
    protected $userDeviceForbidStatus = 0; //用户设备封禁状态 1=>正常 2=>封禁

    /**
     * 初始化的方法
     * @throws ApiException
     */
    protected function _initialize()
    {
        $this->checkRequestAuth();
    }

    /**
     * 检查每次app请求的数据是否合法
     * @throws ApiException
     */
    public function checkRequestAuth()
    {
        // 首先需要获取headers
        $headers = request()->header();
        if (!defined('IS_ACCESS_TOKEN_CHECKED'))
        {
            // sign 加密需要 客户端 ， 解密：服务端
            // 1 headers body 仿照sign 做参数的加解密
            // 2
            // 3
            // 基础参数校验
            if (isset($headers['app-type']))
            {
                if ($headers['app-type'] === 'harmonyos' || strpos(config('app.app_types'), $headers['app-type']) !== false)
                {   // 鸿蒙APP || APP
                    if (!isset($headers['sign']))
                    {
                        Log::write('请求缺少sign', 'error', true);
                        throw new ApiException('接口请求失败');
                    }
                    $type = $headers['app-type'] === 'harmonyos' ? 'harmonyos' : 'app';
                    // 需要sign
                    if (!IAuth::checkSignPass($headers, $type))
                    {
                        Log::write('sign验签失败', 'error', true);
                        throw new ApiException('接口请求失败');
                    }
                } elseif (strpos(config('miniapp.app_types'), $headers['app-type']) !== false)
                {   // 小程序 ｜ H5
                    $this->CT = 2; // 小程序或H5
                } else
                {
                    Log::write('当前设备不支持', 'error', true);
                    throw new ApiException('当前设备不支持');
                }
                // 设备封禁
                $deniedDevices = [
                    '7593FAEA-6461-4673-860E-BC7C8E48440A',
                    '02EDA16B-04B8-4ADB-B4E8-1679884DA45B',
                    '59DCF2E1-52D8-41FA-87F4-8C782E587D3E',
                    'E53616FE-733D-4D43-93BF-E1B37AA62EB5', // 21249780
                    'B91D9D97-478D-4D9F-A391-0B92A1047A59', // 21266114
                    'E4D1CDEF-CC3A-4338-B411-344E0A1BF76C', // 21366028
                    '8453C57F-FD42-49C2-858A-515A2B2B7A18', // 21557648
                    '5AFB735A-28FD-4F29-B7D4-7C6E89C27FC5', // 21566865
                    '5C826068-D814-4ED3-A41C-06BEA7C9E2F5', // 21593038
                    'F53F9B48-AD43-4763-B74C-9A2DE81B50A4', // 21580587
                    '5E121A7E-5F20-4ABB-A28D-55398E76F56B', // 21595914
                    'C076C931-542C-4207-8C7B-CB88D5362D88', // 21601530
                ];
                if (isset($headers['did']) && in_array($headers['did'], $deniedDevices, true))
                {
                    Log::write('当前设备禁止操作：' . $headers['did'], 'error', true);
                    throw new ApiException('当前操作无法执行');
                }
                if (!$this->userDeviceForbidStatus && isset($headers['did']))
                {
                    $userDevice = (new AppUserForbidDeviceRecord())->getUserForbidDeviceInfo($headers['did'], ['status','device_id']);
                    if ($userDevice)
                    {
                        if ((int)$userDevice['status'] === 2)
                        {
                            Log::write('当前设备禁止操作：' . $headers['did'], 'error', true);
                            throw new ApiException('当前操作无法执行');
                        }
                        $this->userDeviceForbidStatus = (int)$userDevice['status'];
                    } else
                    {
                        $this->userDeviceForbidStatus = 1;
                    }
                }
            } else
            {
                Log::write('当前设备不支持', 'error', true);
                throw new ApiException('当前设备不支持');
            }

            // 1、文件  2、mysql 3、redis   由于服务器为集群架构   此处使用redis
            // Cache::set($headers['sign'], 1, config('app.app_sign_cache_time'));
            define('IS_ACCESS_TOKEN_CHECKED', true);
        }
        // 将当前请求头信息存入header属性中，以便后面使用
        $this->headers = $headers;
    }

    /**
     * 判断是否必须绑定手机号
     * @return bool true=>需要  false=>不需要
     */
    public function isMustBindTel()
    {
        if (Util::CheckAppVersion('2.5.0') !== '小')
        {
            $model = $this->request->module();
            $controller = $this->request->controller();
            $startNum = strpos($controller, '.');
            if ($startNum !== false)
            {
                $controller = substr($controller, $startNum + 1);
            }
            $action = $this->request->action(); // 全小写

            $uri = $model . '.' . $controller . '.' . $action;

            $neednotTelData = [ // 免绑手机号接口
                'api.Info.bind_tel',
                'api.Info.change_tel',
                'api.Login.getcode',    // 获取验证码
                'api.Login.outerlogin', // 三方登陆
                'api.Mobile.login', // 一键登录
                'api.login.mobile', // 手机短信验证码登录
                'api.Push.bind', // 推送绑定
                'api.Login.teltokenlogin',
                // 'api.Index.index',  // 首页接口
                // 'api.Info.bind_third',//三方绑定
                // 'api.Info.alter_name',  // 更新昵称
                // 'api.Info.alter_avatar',    // 更新头像
                // 'api.User.getinfo',  // 个人中心
                // 'api.Personal.index', // 个人中心 我的
                // 'api.Feedback.redirecturl', //  把header参数传入到url里
                // 'api.Feedback.gethotquestionlist',  // 获取热门问题列表
                // 'api.Feedback.gethotquestiondetail',    // 获取热门问题详情
                // 'api.Feedback.gettag',  // 获取意见反馈标签
                // 'api.Feedback.getfeedbacklist', // 获取历史反馈列表
                // 'api.Feedback.getfeedbackdetail',   //获取历史反馈列表
                // 'api.Feedback.feedbackadd', //意见反馈
                // 'api.Feedback.feedbackreply',   // 意见反馈会话回复
                // 'api.Feedback.newreplymsg', // 获取意见反馈最新回复
                // 'recode.Index.avatar',  // 上传头像
                //
                // 'api.LogoutAccount.index',      //注销
                // 'api.LogoutAccount.getcode',    //注销
                // 'api.LogoutAccount.getwechatinfo', //注销
                // 'api.LogoutAccount.out',        //注销
                // 'api.LogoutAccount.getuserinfo', //注销 获取三方信息
            ];
            if (in_array($uri, $neednotTelData, true))
            {
                return false;
            }

            if ($this->user['tel'] || $this->user['temporary_tel'])
            {
                return false;
            }

            return true;
        }

        return false;
    }
}
